package com.yanqu.road.server.logic.smallgame.stage;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class WaterBottle {

    private LinkedList<Integer> colors;
    private int deep;

    public WaterBottle(int deep) {
        this.colors = new LinkedList<>();
        this.deep = deep;
    }

    public void addInitColor(List<Integer> colors) {
        for (int color : colors) {
            this.colors.addLast(color);
        }
    }

    public boolean addColor(int color) {
        if (isFull()) {
            return false;
        }
        this.colors.addFirst(color);
        return true;
    }

    public boolean dfsCanPourIn(WaterBottle bottle) {
        if (null == bottle) return false;
        if (bottle.isEmpty()) return false;
        if (this.isFull()) return false;
        if (!this.isEmpty()) {
            if (this.getTopColor() != bottle.getTopColor()) return false;
        } else {
            return !bottle.isOneColor();
        }
        if (this.getEmptySize() < bottle.getTopColors().size()) return false;
        return true;
    }

    //客户端验证操作用，不需要排除纯色管倒空管的情况
    public boolean canPourIn(WaterBottle bottle) {
        if (null == bottle) return false;
        if (bottle.isEmpty()) return false;
        if (this.isFull()) return false;
        if (!this.isEmpty()) {
            if (this.getTopColor() != bottle.getTopColor()) return false;
        }
        if (this.getEmptySize() < bottle.getTopColors().size()) return false;
        return true;
    }


    public int pourIn(WaterBottle bottle) {
        List<Integer> inColors = bottle.getTopColors();
        bottle.removeTopColors();
        for (int color : inColors) {
            this.colors.addFirst(color);
        }
        return inColors.size();
    }

    public void pourBack(WaterBottle bottle, int num) {
        for (int i = 0; i < num; i++) {
            int color = this.colors.removeFirst();
            bottle.addColor(color);
        }
    }

    public List<Integer> getTopColors() {
        List<Integer> topColors = new ArrayList<>();
        int lastColor = 0;
        for (int color : this.colors) {
            if (lastColor == 0)
                lastColor = color;
            if (lastColor != color)
                break;
            topColors.add(color);
        }

        return topColors;
    }

    public int getTopColor() {
        if (this.colors.isEmpty()) {
            return 0;
        }
        return this.colors.getFirst();
    }

    public int getEmptySize() {
        return deep - this.colors.size();
    }

    public void removeTopColors() {
        while (true) {
            int lastColor = this.colors.removeFirst();
            if (this.colors.isEmpty())
                break;
            if (lastColor != this.colors.getFirst())
                break;
        }

    }

    public boolean isFull() {
        if (colors.size() == deep) {
            return true;
        }
        return false;
    }

    public boolean isEmpty() {
        return colors.isEmpty();
    }

    public boolean isOneColor() {
        int lastColor = 0;
        for (int color : this.colors) {
            if (lastColor == 0) {
                lastColor = color;
            }
            if (lastColor != color) {
                return false;
            }
        }

        return true;
    }

    public boolean isOneFullColor() {
        if (this.colors.isEmpty()) return false;
        if (this.colors.size() != deep) return false;
        int lastColor = 0;
        for (int color : this.colors) {
            if (lastColor == 0) {
                lastColor = color;
            }
            if (lastColor != color) {
                return false;
            }
        }

        return true;
    }

    public String toString() {
        String colorStr = "|";
        for (int color : this.colors) {
            colorStr += String.valueOf(color) + "|";
        }
        return colorStr;
    }

    public List<Integer> getColors() {
        List<Integer> result = new ArrayList<>();
        for (Integer color : this.colors) {
            result.add(color);
        }
        return result;
    }
}
